package com.ruoyi.flowable.service;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.SecurityUtils;
import com.zgl.youshuda.client.YoushudaClient;
import com.zgl.youshuda.client.utils.OperResult;
import com.zgl.youshuda.core.service.procservice.util.callservice.GetBeanUtils;
import com.zgl.youshuda.core.service.procservice.util.callservice.domain.MksServerInfo;
import com.zgl.youshuda.core.utils.CommonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import javax.management.*;
import java.lang.management.ManagementFactory;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@Slf4j
@Service
public class YsdProcExecService {

    public static YsdProcExecService getInstance(){
        return new YsdProcExecService();
    }

    /**
     * 调用优树搭
     * @param procTarget
     */
    public void exec(String procTarget,Map<String,Object> reqBody){
        if(reqBody==null || reqBody.size()<=0){
            throw new RuntimeException("处理异常，流程请求参数不能为空");
        }
        /**
         * 请求优树搭
         */
        YoushudaClient youshudaClient=new YoushudaClient();
        //优树搭服务器地址
        MksServerInfo mksServerInfo = getMksServerInfo();
        String youshudaAddr="http://"+mksServerInfo.getIp()+":" + mksServerInfo.getPort() + mksServerInfo.getContextPath()+"/";
        youshudaClient.setYoushudaAddr(youshudaAddr);
        //优树搭应用ID
        youshudaClient.setAppId("bf1f01fbc321a5f0097691efb78b49c8");
        /**
         * 流程接口标识
         */
        youshudaClient.setProcTarget(procTarget);
        /**
         * 请求头信息
         */
        Map<String, String> headers = new HashMap<>();
        //添加 token
        try{
            headers.put("Authorization",SecurityUtils.getLoginUser().getToken());
        }catch (Exception e){}
        youshudaClient.setHeaders(headers);
        /**
         * 请求参数
         */
        youshudaClient.setReqBody(reqBody);
        /**
         * 请求执行
         */
        OperResult reqResult = youshudaClient.send();

        System.out.println("优树搭请求执行结果=====>"+ JSONObject.toJSONString(reqResult));
        //执行失败
        if(!reqResult.isSuccess()){
            throw new RuntimeException(reqResult.getMsg());
        }
        OperResult procExecResult = JSONObject.parseObject(String.valueOf(reqResult.getData()), OperResult.class);
        if(!procExecResult.isSuccess()){
            throw new RuntimeException(procExecResult.getMsg());
        }
    }

    private MksServerInfo getMksServerInfo() {

        ApplicationContext applicationContext = GetBeanUtils.getApplicationContext();

        Environment environment = applicationContext.getEnvironment();
        //操作系统
        String osName = environment.getProperty("os.name");
        /**
         * 1、先获取是否存在外置tomcat，当项目是否war包在tomcat中运行时
         */
        String _port = getTomcatPort();
        if(CommonUtil.stringIsNull(_port)){
            /**
             * 当没有获取到外置tomcat端口时，尝试获取配置文件中的端口
             */
            _port = environment.getProperty("server.port");
            if (CommonUtil.stringIsNull(_port)) {
                _port = "8080";
            }
        }
        //项目名
        String _projectName = environment.containsProperty("server.servlet.context-path") ? environment.getProperty("server.servlet.context-path") : "";
        /**
         * 获取当前服务器IP
         */
        String ip = getIpAddress();
        if (CommonUtil.stringIsNull(ip)) {
            ip = "127.0.0.1";
        }

        return new MksServerInfo(osName, ip, _port, _projectName);
    }


    /**
     * 获取tomcat端口
     *
     * @return
     */
    private String getTomcatPort() {
        MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
        try {
            QueryExp protocol = Query.match(Query.attr("protocol"), Query.value("HTTP/1.1"));
            ObjectName name = new ObjectName("*:type=Connector,*");
            Set<ObjectName> objectNames = beanServer.queryNames(name, protocol);
            for (ObjectName objectName : objectNames) {
                String catalina = objectName.getDomain();
                if ("Catalina".equals(catalina)) {
                    return objectName.getKeyProperty("port");
                }
            }
        } catch (MalformedObjectNameException e) {
            log.error("获取tomcat端口异常", e);
        }
        return "";
    }

    /**
     * 获取当前服务器IP地址
     *
     * @return
     */
    private String getIpAddress() {
        try {
            //从网卡中获取IP
            Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            InetAddress ip;
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
                //用于排除回送接口,非虚拟网卡,未在使用中的网络接口
                if (!netInterface.isLoopback() && !netInterface.isVirtual() && netInterface.isUp()) {
                    //返回和网络接口绑定的所有IP地址
                    Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
                    while (addresses.hasMoreElements()) {
                        ip = addresses.nextElement();
                        if (ip != null && ip instanceof Inet4Address) {
                            return ip.getHostAddress();
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("IP地址获取失败", e);
        }
        return "";
    }
}
